import os
import xml.etree.ElementTree as ET
import time
import tempfile
import subprocess
import json


def node_to_dict(node):
    """将节点转换为字典格式，过滤掉空节点"""
    result = {}
    for key, value in node.attrib.items():
        result[key] = value

    children = []
    for child in node:
        child_dict = node_to_dict(child)
        if child_dict:  # 只添加非空的子节点
            children.append(child_dict)

    if children:
        result['children'] = children

    return result


def dict_to_spans(node_dict, level=0):
    """递归将节点字典转换为ul/li标签层级展示"""
    if not node_dict:
        return ""

    # 如果是顶层且class为Unknown，直接显示子节点
    if level == 0 and node_dict.get('class') == 'Unknown' and 'children' in node_dict:
        html = ['<ul class="tree">']
        for child in node_dict['children']:
            html.append(dict_to_spans(child, level))
        html.append('</ul>')
        return '\n'.join(html)

    # 获取节点属性
    class_name = node_dict.get('class', '')
    desc = node_dict.get('content-desc', '')
    text = node_dict.get('text', '')
    clickable = node_dict.get('clickable', 'false').lower() == 'true'

    # 构建显示文本
    display_text = class_name.replace('android.widget.', '').replace('android.view.', '')
    if desc:
        display_text += f'  {desc}'
    if text:
        display_text += f'  {text}'

    # 构建节点数据属性字符串
    node_data = {k: v for k, v in node_dict.items() if k != 'children'}
    node_data_str = json.dumps(node_data, ensure_ascii=False).replace('"', '&quot;')

    # 构建当前节点的HTML
    has_children = 'children' in node_dict and node_dict['children']
    clickable_class = 'clickable' if clickable else ''
    icon_class = 'folder' if has_children else 'file'

    html = [
        f'<li>',
        f'<div class="node-wrapper">',
        f'<span class="toggle-btn">{"-" if has_children else ""}</span>' if has_children else '<span class="toggle-btn"></span>',
        f'<span class="node {clickable_class} {icon_class}" data-node=\'{node_data_str}\'>{display_text}</span>',
        f'<button class="detail-btn" data-node=\'{node_data_str}\'>详情</button>',
        f'</div>'
    ]

    # 如果有子节点，添加ul标签（默认展开）
    if has_children:
        html.append('<ul>')
        for child in node_dict['children']:
            child_html = dict_to_spans(child, level + 1)
            if child_html:
                html.append(child_html)
        html.append('</ul>')

    html.append('</li>')
    return '\n'.join(html)


def get_accessibility_nodes():
    """获取无障碍节点信息并截图"""
    try:
        # 获取节点信息
        subprocess.run('adb shell uiautomator dump /sdcard/window_dump.xml', shell=True, check=True)
        # 获取屏幕截图
        subprocess.run('adb shell screencap -p /sdcard/screen.png', shell=True, check=True)
        time.sleep(0.5)

        temp_dir = tempfile.gettempdir()
        temp_xml = os.path.join(temp_dir, 'window_dump.xml')
        temp_png = os.path.join('screen.png')  # 保存到当前目录

        # 拉取文件
        subprocess.run(f'adb pull /sdcard/window_dump.xml "{temp_xml}"', shell=True, check=True)
        subprocess.run(f'adb pull /sdcard/screen.png "{temp_png}"', shell=True, check=True)

        tree = ET.parse(temp_xml)
        root = tree.getroot()
        nodes_dict = node_to_dict(root)

        try:
            os.remove(temp_xml)
        except:
            pass

        return nodes_dict

    except Exception as e:
        print(f"获取无障碍节点出错: {str(e)}")
        return {}


if __name__ == "__main__":
    result = subprocess.getoutput('adb devices')
    if 'device' not in result:
        print("未检测到设备，请确保：")
        print("1. 手机已通过USB连接到电脑")
        print("2. 已在手机上允许USB调试")
    else:
        # 获取节点
        nodes = get_accessibility_nodes()

        # 读取模板文件并替换占位符
        with open('template.html', 'r', encoding='utf-8') as f:
            template = f.read()

        tree_content = dict_to_spans(nodes)
        html_content = template.replace('{tree_content}', tree_content)

        # 保存为HTML文件
        with open('nodes.html', 'w', encoding='utf-8') as f:
            f.write(html_content)

        print("已生成nodes.html文件，请在浏览器中打开查看")
